package cn.edu.tsinghua.xkk.correction;

import java.util.LinkedList;
import java.util.List;

public class WholeIndex
{
	public WordIndex myIndex = null;
	
	public WholeIndex ()
	{
		myIndex = new WordIndex (-1);
	}
	
	public void add (String target, int pos)
	{
		WordIndex here = myIndex;
		
		for (int i = 0; i < target.length(); i++)
		{
			if (!(target.charAt(i) >= 'a' && target.charAt(i) <= 'z'))
			{
				here.thisLevel.add(pos);
				return;
			}
			int isin = -1;
			for (int j = 0; j < here.nextLevel.size(); j++)
			{
				if (here.nextLevel.get(j).sig == target.charAt(i))
				{
					isin = j;
					break;
				}
			}
			
			if (isin >= 0)
			{
				here = here.nextLevel.get(isin);
			}
			else
			{
				WordIndex tmp = new WordIndex (i);
				tmp.sig = target.charAt(i);
				here.nextLevel.add(tmp);
				here = here.nextLevel.get(here.nextLevel.size() - 1);
			}
		}
		
		here.thisLevel.add(pos);
	}
	
	public List <Integer> search (String target)
	{
		List <Integer> result = new LinkedList <Integer> ();
		
		WordIndex here = myIndex;
		int pos = 0;
		
		for (int i = 0; i < target.length(); i++)
		{
			if (here.nextLevel.size() != 0)
			{
				boolean reachEnd = true;
				for (int j = 0; j < here.nextLevel.size(); j++)
				{
					if (here.nextLevel.get(j).sig == target.charAt(i))
					{
						here = here.nextLevel.get(j);
						reachEnd = false;
						break;
					}
				}
				
				if (reachEnd || i >= target.length() - 1)
				{
					pos = i;
					break;
				}
			}
		}
		if (pos >= target.length() * 0.75)
		{
			result.addAll(here.searchAll());
		}
		
		return result;
	}
	
	public List <Integer> correctSearch (String target)
	{
		List <Integer> result = new LinkedList <Integer> ();
		
		WordIndex here = myIndex;
		int pos = 0;
		
		for (int i = 0; i < target.length(); i++, pos = i)
		{
			if (!(target.charAt(i) >= 'a' && target.charAt(i) <= 'z'))
			{
				result.addAll(here.searchThisLevel());
			}
			if (here.nextLevel.size() != 0)
			{
				for (int j = 0; j < here.nextLevel.size(); j++)
				{
					if (here.nextLevel.get(j).sig == target.charAt(i))
					{
						here = here.nextLevel.get(j);
						break;
					}
				}
			}
		}
		
		if (pos == target.length())
		{
			result.addAll(here.searchThisLevel());
		}
		
		return result;
	}
}
